#include <QTimer>
#include <QStringList>
#include <QMessageBox>
#include <QSettings>
#include <QCoreApplication>
#include <QFileInfo>
#include <QDir>
#include "datamanagement.h"


DataManagement::DataManagement(QObject *parent) :
    QObject(parent)
{
    initStockData();
    initStockKLineData();

    m_pNetAccMgr = new QNetworkAccessManager(this);

    connect(m_pNetAccMgr, SIGNAL(finished(QNetworkReply*)),
            this, SLOT(slotReplyFinished(QNetworkReply*)));

    slotUpdateStockData();
    m_tempStock = "";
    QTimer *timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this, SLOT(slotUpdateStockData()));
    timer->start(1000);
}

DataManagement::~DataManagement()
{

}

bool DataManagement::initStockData()
{
    QString path = QCoreApplication::applicationDirPath() + "/data";
    QFileInfo fileInfo(QDir(path), "StockAnalyzer.ini");
    if(fileInfo.exists())
    {
        qDebug()<<"**********************";
        QSettings settings(fileInfo.absoluteFilePath(), QSettings::IniFormat);
        settings.beginGroup("stock code");
        int count = settings.value("count").toInt();
        for(int index = 0; index < count; index++)
        {
            QString stockCode = settings.value(QString::number(index)).toString();
            m_stockCodeList.append(stockCode);
        }
    }
    else
    {
        return false;
    }


    return true;
}

void DataManagement::initStockKLineData()
{
    QString path = QCoreApplication::applicationDirPath() + "/data";
    QFile file(path + "/kdata.txt");

    if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
        return;

    while (!file.atEnd()) {
        QByteArray line = file.readLine();
        QString str(line);

        QStringList list = str.split(",");
        KLINEDATA kdata;
        kdata.sStockCode= list.at(0);
        kdata.fMAFive   = list.at(1).toDouble();
        kdata.fMATen    = list.at(2).toDouble();
        kdata.fMATwenty = list.at(3).toDouble();
        kdata.fMAThirty = list.at(4).toDouble();
        kdata.fMASixty  = list.at(5).toDouble();

        m_KLineList.append(kdata);
    }
}

void DataManagement::getStockKLineData(STOCKINFO &stockinfor)
{
    foreach(KLINEDATA kdata, m_KLineList)
    {
        if(kdata.sStockCode == stockinfor.sStockCode)
        {
            stockinfor.fMAFive   = kdata.fMAFive;
            stockinfor.fMATen    = kdata.fMATen;
            stockinfor.fMATwenty = kdata.fMATwenty;
            stockinfor.fMAThirty = kdata.fMAThirty;
            stockinfor.fMASixty  = kdata.fMASixty;
        }
    }
}

QString DataManagement::analyzeThisStock(STOCKINFO &stockinfor)
{
    double currentPrice = stockinfor.fCurrentPrice;

    QList<double> list;
    list.append(stockinfor.fMAFive);
    list.append(stockinfor.fMATen);
    list.append(stockinfor.fMATwenty);
    list.append(stockinfor.fMAThirty);
    list.append(stockinfor.fMASixty);

    foreach(double value, list)
    {
        double diff = currentPrice - value;
        double percent = diff/currentPrice;
        if(qAbs(percent) < 0.002 && diff > 0)
        {
            return "purchase";
        }
    }

    if(stockinfor.fRangeExtent < -0.0215)
    {
        return "sale";
    }

    return "-";
}

void DataManagement::slotReplyFinished(QNetworkReply* reply)
{
    QByteArray byteData = reply->readAll();
    QString stockStr(byteData);

    //parse stock info
    obtainStocksOrgInfo(stockStr);
}

void DataManagement::slotUpdateStockData()
{
    QString url = "http://hq.sinajs.cn/list=";

    if(m_stockCodeList.count() == 0)
    {
        url += "sh000001";
    }
    else if(m_stockCodeList.count())
    {
        url += m_stockCodeList.join(",");
//        qDebug()<<"      ******new url: "<<url;
    }

    m_pNetAccMgr->get(QNetworkRequest(url));
}

void DataManagement::slotAddSelectedStock(int code)
{
    QString stockCode = "";
    if(code < 100000)
    {
        code += 1000000;

        stockCode = QString::number(code);
        stockCode = "sz" + stockCode.right(6);
    }
    else if(code < 399999)
    {
        stockCode = QString::number(code);
        stockCode = "sz" + stockCode;
    }
    else if( code >= 600000)
    {
        stockCode = QString::number(code);
        stockCode = "sh" + stockCode;
    }
    else
    {
        return;
    }

    if(!m_stockCodeList.contains(stockCode))
    {
//        m_stockCodeList.append(stockCode);
        m_tempStock = stockCode;
    }

    qDebug()<<"***************************************Stock Code: "<<stockCode;
}

void DataManagement::slotDeleteSelectedStock(int index)
{
    if(m_stockCodeList.count())
        m_stockCodeList.removeAt(index);
}

void DataManagement::processStockData(QStringList &infoList, STOCKORGINFO
                                      &stockSrcinfo, STOCKINFO &stockTarInfo)
{
    QString str = infoList.at(0);
    int from = str.indexOf("str_") + 6;
    stockSrcinfo.sStockCode = str.midRef(from, 6).toString();
    stockSrcinfo.sStockName = str.section("\"", 1, 1);
    stockSrcinfo.fStartPrice = infoList.at(1).toDouble();
    stockSrcinfo.fLastEndPrice = infoList.at(2).toDouble();
    stockSrcinfo.fCurrentPrice = infoList.at(3).toDouble();

    stockSrcinfo.fTopPrice = infoList.at(4).toDouble();
    stockSrcinfo.fFootPrice = infoList.at(5).toDouble();
    stockSrcinfo.fBuyPrice = infoList.at(6).toDouble();
    stockSrcinfo.fSalePrice = infoList.at(7).toDouble();
    stockSrcinfo.fStockSum = infoList.at(8).toDouble();
    stockSrcinfo.fTradeValue = infoList.at(9).toDouble();

    stockSrcinfo.fFirstBuySum = infoList.at(10).toDouble();
    stockSrcinfo.fFirstBuyPrice = infoList.at(11).toDouble();
    stockSrcinfo.fSecondBuySum = infoList.at(12).toDouble();
    stockSrcinfo.fSecondBuyPrice = infoList.at(13).toDouble();
    stockSrcinfo.fThirdBuySum = infoList.at(14).toDouble();
    stockSrcinfo.fThirdBuyPrice = infoList.at(15).toDouble();
    stockSrcinfo.fFourthBuySum = infoList.at(16).toDouble();
    stockSrcinfo.fFourthBuyPrice = infoList.at(17).toDouble();
    stockSrcinfo.fFifthBuySum = infoList.at(18).toDouble();
    stockSrcinfo.fFifthBuyPrice = infoList.at(19).toDouble();

    stockSrcinfo.fFirstSaleSum = infoList.at(20).toDouble();
    stockSrcinfo.fFirstSalePrice = infoList.at(21).toDouble();
    stockSrcinfo.fSecondSaleSum = infoList.at(22).toDouble();
    stockSrcinfo.fSecondSalePrice = infoList.at(23).toDouble();
    stockSrcinfo.fThirdSaleSum = infoList.at(24).toDouble();
    stockSrcinfo.fThirdSalePrice = infoList.at(25).toDouble();
    stockSrcinfo.fFourthSaleSum = infoList.at(26).toDouble();
    stockSrcinfo.fFourthSalePrice = infoList.at(27).toDouble();
    stockSrcinfo.fFifthSaleSum = infoList.at(28).toDouble();
    stockSrcinfo.fFifthSalePrice = infoList.at(29).toDouble();

    stockSrcinfo.dCurrentDate = QDate::fromString(infoList.at(30), Qt::ISODate);
    stockSrcinfo.tCurrentTime = QTime::fromString(infoList.at(31), Qt::ISODate);

    dataProcess(stockSrcinfo, stockTarInfo);
}

void DataManagement::dataProcess(STOCKORGINFO &stockSrcinfo, STOCKINFO &stockTarInfo)
{
    stockTarInfo.sStockCode = stockSrcinfo.sStockCode.right(6);
    stockTarInfo.sStockName = stockSrcinfo.sStockName;

    double balance = stockSrcinfo.fCurrentPrice - stockSrcinfo.fLastEndPrice;
    double percentage = balance / stockSrcinfo.fLastEndPrice;

    stockTarInfo.fRangeExtent = KeepDecimal(percentage, 4);
    stockTarInfo.fCurrentPrice = stockSrcinfo.fCurrentPrice;
    stockTarInfo.fDifference = KeepDecimal(balance, 2);

    stockTarInfo.fStartPrice = stockSrcinfo.fStartPrice;
    stockTarInfo.fLastEndPrice = stockSrcinfo.fLastEndPrice;
    stockTarInfo.fTopPrice = stockSrcinfo.fTopPrice;
    stockTarInfo.fFootPrice = stockSrcinfo.fFootPrice;

    stockTarInfo.fBuyPrice = stockSrcinfo.fBuyPrice;
    stockTarInfo.fSalePrice = stockSrcinfo.fSalePrice;
    stockTarInfo.fStockSum = qRound(stockSrcinfo.fStockSum / 100);
    stockTarInfo.fTradeValue = qRound(stockSrcinfo.fTradeValue/10000);

    stockTarInfo.fPERatio = 0;
    stockTarInfo.fTurnoverRate = 0;

//    stockTarInfo.fMAFive = 0;
//    stockTarInfo.fMATen = 0;
//    stockTarInfo.fMATwenty = 0;
//    stockTarInfo.fMAThirty = 0;
//    stockTarInfo.fMASixty = 0;
    getStockKLineData(stockTarInfo);

    stockTarInfo.dCurrentDate = stockSrcinfo.dCurrentDate;
    stockTarInfo.tCurrentTime = stockSrcinfo.tCurrentTime;
    stockTarInfo.fgColor = getForegroundColor(balance);
    stockTarInfo.bgColor = getBackgroundColor();
    stockTarInfo.sRecommend = analyzeThisStock(stockTarInfo);
}

QColor DataManagement::getForegroundColor(double balance)
{
    if(balance > 0)
    {
        return QColor("red");
    }
    else if(balance < 0)
    {
        return QColor("green");
    }

    return QColor("white");
}

QColor DataManagement::getBackgroundColor()
{
    //parse the data, and get the result

    return QColor("white");
}

void DataManagement::obtainStocksOrgInfo(QString &stockStr)
{
//    ()<<"\n*****************obtainStocksOrgInfo";
//    ()<<"     ************stockStr:"<<stockStr;

    QHash<int, STOCKINFO> stocksInfoHash;
    QStringList stocksInfoList = stockStr.split(";", QString::SkipEmptyParts);


    QString date = QDate::currentDate().toString("yyyy-MM-dd");
//    stocksInfoList = stocksInfoList.filter(date);

    foreach(QString str, stocksInfoList)
    {
        if(!str.contains(date))
        {
            int index = stocksInfoList.indexOf(str);
            stocksInfoList.removeAt(index);
            m_stockCodeList.removeAt(index);
        }
    }


    int count = stocksInfoList.count();
    if(m_tempStock != "")
    {
        m_stockCodeList.append(m_tempStock);
        m_tempStock = "";
    }

    if(count)
    {
        for(int index = 0; index < count; index++)
        {
            STOCKORGINFO stockOrginfo;
            STOCKINFO    stockTarInfo;

            QString stock = stocksInfoList.at(index);
            QStringList infoList = stock.split(",");
//            qDebug()<<tr("     ************stock %1:%2").arg(index).arg(stocksInfoList.at(index));
            processStockData(infoList, stockOrginfo, stockTarInfo);

            stocksInfoHash.insert(index, stockTarInfo);
        }

        emit signalSendData(stocksInfoHash);
    }

}

void DataManagement::saveStockData()
{
    QString path = QCoreApplication::applicationDirPath() + "/data";
    QFile file(path + "/StockAnalyzer.ini");
    if(file.exists())
    {
        file.remove();
    }


    QSettings settings(QCoreApplication::applicationDirPath() +
                       "/data/StockAnalyzer.ini", QSettings::IniFormat);
    settings.beginGroup("stock code");

    int count = m_stockCodeList.count();
    settings.setValue("count", count);

    for(int index = 0; index < count; index++)
    {
        settings.setValue(QString::number(index), m_stockCodeList.at(index));
    }

    settings.endGroup();
}
